﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace TasksModel
{
    [System.Xml.Serialization.XmlRootAttribute(Namespace = "http://mp.tasks.com/2010/")]
    public class TaskObservableCollection<T> : System.Collections.ObjectModel.ObservableCollection<T>,
        IOrderedEnumerable<T>
    {
        public TaskObservableCollection()
        {
        }

        public TaskObservableCollection(IEnumerable<T> collection)
            : base(collection)
        {
        }

        public TaskObservableCollection(List<T> list)
            : base(list)
        {
        }

        private bool _disallowEvent;

        [System.Diagnostics.DebuggerStepThrough]
        //[System.Runtime.TargetedPatchingOptOut("Performance critical")]
        public void SuspendChangedEvents()
        {
            _disallowEvent = true;
        }

        [System.Diagnostics.DebuggerStepThrough]
        //[System.Runtime.TargetedPatchingOptOut("Performance critical")]
        public void ResumeChangedEvents()
        {
            _disallowEvent = false;
        }

        protected override void OnCollectionChanged(System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
        {
            if (!_disallowEvent)
                base.OnCollectionChanged(e);
        }

        protected override void OnPropertyChanged(System.ComponentModel.PropertyChangedEventArgs e)
        {
            if (!_disallowEvent)
                base.OnPropertyChanged(e);
        }

        public IOrderedEnumerable<T> CreateOrderedEnumerable<TKey>(
            Func<T, TKey> keySelector, IComparer<TKey> comparer, bool descending)
        {
            // get sort order
            IOrderedEnumerable<T> o = descending ?
                this.OrderByDescending(keySelector, comparer) :
                this.OrderBy(keySelector, comparer);
            // create list in order
            TaskObservableCollection<T> res = new TaskObservableCollection<T>();
            res.SuspendChangedEvents();
            foreach (T s in o)
                res.Add(s);
            res.ResumeChangedEvents();
            return res;
        }
    }
}